﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
using EngineOfEvermore.Imaging;

namespace EngineOfEvermore.Editor.AnimationEditor.Presenter
{
    class Presenter : View.IInputListener
    {
        class Document
        {
            public Document()
            { }

            public Document( View.IDocumentView view, Model.IDocumentModel model )
            {
                this.View = view;
                this.Model = model;
            }

            public View.IDocumentView View;
            public Model.IDocumentModel Model;
            public readonly HashSet<String> ReferencedImageMaps = new HashSet<String>();
        }

        View.IView _view;
        Model.IAnimationEditorModel _model;
        List<Document> _documents = new List<Document>();
        Document _activeDocument;
        bool _allowClosingMainForm;

        public View.IView AppView
        {
            get { return _view; }
            set { _view = value; }
        }

        public Model.IAnimationEditorModel AppModel
        {
            get { return _model; }
            set { _model = value; }
        }

        public void OnNewDocumentClicked()
        {
            Document doc = new Document();

            doc.View = _view.CreateNewDocument();
            doc.Model = _model.CreateNewDocument();

            _documents.Add( doc );

            doc.View.DisplayedAnimation = doc.Model.EditedAnimation;

            _activeDocument = doc;

            _view.ImageMapView.ResetView();

            // TODO: doc title
        }

        public void OnDocumentClosing( View.IDocumentView docView, FormClosingEventArgs e )
        {
            Document doc = _documents.Find( d => d.View == docView );

            Debug.Assert( doc != null );

            _model.DestroyDocument( doc.Model );
            _documents.Remove( doc );
        }

        public void OnShowAnimationExplorerClicked()
        {
            _view.ShowAnimationExplorer();
        }

        public void OnShowImageMapViewClicked()
        {
            _view.ShowImageMapView();
        }

        public void OnCloseClicked( FormClosingEventArgs e )
        {
            if ( !_allowClosingMainForm )
            { 
                // Do a check for unsaved changes etc...
            }
        }

        public void OnOpenAnimationRequest( String resourceName )
        {
            Document doc = 
                _documents.Find( x => x.Model.NameOfRepresentedResource == resourceName );

            if ( doc != null )
            {
                _view.BringDocumentToFocus( doc.View );
                _activeDocument = doc;
            }
            else
            {
                doc = new Document();
                doc.Model = _model.LoadResourceAsDocument( resourceName );
                doc.View = _view.CreateNewDocument();

                doc.View.DisplayedAnimation = doc.Model.EditedAnimation;
                doc.View.DocumentTitle = resourceName;

                for ( int i = 0; i < doc.Model.EditedAnimation.FrameCount; ++i )
                {
                    AnimationFrame frame = doc.Model.EditedAnimation[i];

                    foreach ( AnimationSubFrame subFrame in frame.SubFrames )
                    {
                        if ( !doc.ReferencedImageMaps.Contains( subFrame.ImageMap.ResourceName ) )
                        {
                            _view.ImageMapView.LoadImageMap( subFrame.ImageMap.ResourceName );
                            doc.ReferencedImageMaps.Add( subFrame.ImageMap.ResourceName );
                        }
                    }
                }
                
                _documents.Add( doc );

                _setDocumentActive( doc );
            }
        }

        public void OnDocumentActivated( View.IDocumentView documentView )
        {
            Document doc = _documents.Find( d => d.View == documentView );
            _setDocumentActive( doc );
        }

        public void OnLoadImageMapClicked()
        {
            if ( _activeDocument != null )
            {
                String resourceName = _view.ShowImageMapLoadingDialog();

                if ( !_activeDocument.ReferencedImageMaps.Contains( resourceName ) )
                {
                    _activeDocument.ReferencedImageMaps.Add( resourceName );
                    _view.ImageMapView.LoadImageMap( resourceName );
                }
            }
        }

        public void OnSelectImageMap( string resourceName )
        {
            Debug.Assert( _activeDocument != null );
        } 

        void _setDocumentActive( Document document )
        {
            if ( document != _activeDocument )
            {
                _activeDocument = document;
                _view.ImageMapView.ResetView();

                if ( _activeDocument != null )
                {
                    foreach ( String imageMapName in _activeDocument.ReferencedImageMaps )
                    {
                        _view.ImageMapView.LoadImageMap( imageMapName );
                    }

                    _view.ImageMapView.ContentEnabled = true;
                }
                else
                {
                    _view.ImageMapView.ContentEnabled = false;
                }
            }
        }
    }
}
